#include "mini_redis/KeyValueStore.h"
#include <algorithm>
#include <chrono>
#include <cstdint>
#include <cstdlib>
#include <iterator>
#include <memory>
#include <mutex>
#include <optional>
#include <utility>
#include <vector>

namespace mini_redis {

using HashRecordVector = std::vector<std::pair<std::string, HashRecord>>;

using ValueRecordVector = std::vector<std::pair<std::string, ValueRecord>>;

/**********************普通字符串****************************/

int64_t KeyValueStore::nowMs()
{
    using namespace std::chrono;
    return duration_cast<milliseconds>(
               steady_clock::now().time_since_epoch())
        .count();
}

bool KeyValueStore::isExpired(const ValueRecord& r, int64_t now_ms)
{
    return r.expire_at_ms >= 0 && now_ms >= r.expire_at_ms;
}

void KeyValueStore::cleanupIfExpired(const std::string& key,
                                     int64_t            now_ms)
{
    auto it = map_.find(key);
    if (it == map_.end())
        return;
    if (isExpired(it->second, now_ms))
    {
        map_.erase(it);
        expire_index_.erase(key);
    }
}

bool KeyValueStore::set(const std::string& key, const std::string& value,
                        std::optional<int64_t> ttl_ms)
{
    std::lock_guard<std::mutex> lock(mutex_);
    int64_t                     expire_at = -1;
    if (ttl_ms.has_value())
    {
        expire_at = nowMs() + *ttl_ms;
    }

    map_[key] = ValueRecord{value, expire_at};

    if (expire_at >= 0)
        expire_index_[key] = expire_at;
    else
        expire_index_.erase(key);

    return true;
}

// 设置字符串类型键值对并直接指定过期时间戳
bool KeyValueStore::setWithExpireAtMs(const std::string& key,
                                      const std::string& value,
                                      int64_t            expire_at_ms)
{
    std::lock_guard<std::mutex> lock(mutex_);
    map_[key] = ValueRecord{value, expire_at_ms};
    if (expire_at_ms >= 0)    // 包含0（立即过期）的有效情况
        expire_index_[key] = expire_at_ms;
    else    // 永不过期时，从索引中移除
        expire_index_.erase(key);
    return true;
}

std::optional<std::string> KeyValueStore::get(const std::string& key)
{
    std::lock_guard<std::mutex> lock(mutex_);
    int64_t                     now_ms = nowMs();
    cleanupIfExpired(key, now_ms);
    auto it = map_.find(key);

    if (it == map_.end())
        return std::nullopt;

    return it->second.value;
}

int KeyValueStore::del(const std::vector<std::string>& keys)
{
    std::lock_guard<std::mutex> lock(mutex_);

    int64_t now_ms  = nowMs();
    int     removed = 0;

    for (auto& k : keys)
    {
        cleanupIfExpired(k, now_ms);
        auto it = map_.find(k);

        if (it != map_.end())
        {
            map_.erase(k);
            expire_index_.erase(k);
            removed++;
        }
    }

    return removed;
}

bool KeyValueStore::exists(const std::string& key)
{
    std::lock_guard<std::mutex> lk(mutex_);
    int64_t                     now = nowMs();
    cleanupIfExpired(key, now);        // 清理字符串
    cleanupIfExpiredHash(key, now);    // 清理哈希
    cleanupIfExpiredZSet(key, now);    // 清理有序集合
    return map_.find(key) != map_.end() ||
           hmap_.find(key) != hmap_.end() ||
           zmap_.find(key) != zmap_.end();
}

bool KeyValueStore::expire(const std::string& key, int64_t ttl_seconds)
{
    std::lock_guard<std::mutex> lock(mutex_);

    int64_t now = nowMs();

    cleanupIfExpired(key, now);

    auto it = map_.find(key);

    if (it == map_.end())
        return false;

    if (ttl_seconds < 0)
    {
        it->second.expire_at_ms = -1;
        expire_index_.erase(key);
        return true;
    }

    it->second.expire_at_ms = now + ttl_seconds * 1000;
    expire_index_[key]      = it->second.expire_at_ms;
    return true;
}

int64_t KeyValueStore::ttl(const std::string& key)
{
    std::lock_guard<std::mutex> lock(mutex_);
    int64_t                     now_ms = nowMs();
    cleanupIfExpired(key, now_ms);

    auto it = map_.find(key);
    if (it == map_.end())
    {
        return -2;    // 不存在
    }

    if (it->second.expire_at_ms == -1)
    {
        return -1;    // 永不过期
    }

    // 剩余的存活日期
    int64_t ms_left = it->second.expire_at_ms - now_ms;
    if (ms_left < 0)
    {
        return -2;    // 已过期但未被清理
    }

    return ms_left / 1000;
}

int KeyValueStore::expireScanStep(int max_steps)
{
    std::lock_guard<std::mutex> lock(mutex_);
    if (max_steps <= 0 || expire_index_.empty())
        return 0;
    int     removed = 0;
    int64_t now     = nowMs();
    // random starting point
    auto it = expire_index_.begin();
    std::advance(
        it, static_cast<long>(static_cast<unsigned long>(std::rand()) %
                              expire_index_.size()));

    for (int i = 0; i < max_steps && !expire_index_.empty(); ++i)
    {
        if (it == expire_index_.end())
            it = expire_index_.begin();
        const std::string key  = it->first;
        int64_t           when = it->second;
        if (when >= 0 && now >= when)
        {
            map_.erase(key);
            hmap_.erase(key);
            zmap_.erase(key);
            it = expire_index_.erase(it);
            ++removed;
        }
        else
        {
            ++it;
        }
    }
    return removed;
}

ValueRecordVector KeyValueStore::snapshot() const
{
    std::lock_guard<std::mutex> lock(mutex_);

    std::vector<std::pair<std::string, ValueRecord>> out;
    out.reserve(map_.size());
    for (auto& kv : map_)
    {
        out.emplace_back(kv.first, kv.second);
    }

    return out;
}

/**********************普通字符串****************************/

/**********************哈希****************************/

bool KeyValueStore::isExpired(const HashRecord& r, int64_t now_ms)
{
    return r.expire_at_ms >= 0 && now_ms >= r.expire_at_ms;
}

void KeyValueStore::cleanupIfExpiredHash(const std::string& key,
                                         int64_t            now_ms)
{
    auto it = hmap_.find(key);
    if (it == hmap_.end())
        return;
    if (isExpired(it->second, now_ms))
    {
        hmap_.erase(it);
        expire_index_.erase(key);
    }
}

int KeyValueStore::hset(const std::string& key, const std::string& field,
                        const std::string& value)
{
    std::lock_guard<std::mutex> lock(mutex_);

    // 清理过期的哈希键：
    int64_t now_ms = nowMs();
    cleanupIfExpiredHash(key, now_ms);

    // 获取或创建哈希记录
    auto& rec = hmap_[key];

    // 检查字段是否存在
    auto it = rec.fields.find(field);

    // 处理新字段（不存在）
    if (it == rec.fields.end())
    {
        rec.fields[field] = value;
        return 1;
    }

    // 处理已有字段（存在）
    it->second = value;
    return 0;
}

std::optional<std::string> KeyValueStore::hget(const std::string& key,
                                               const std::string& field)
{
    std::lock_guard<std::mutex> lock(mutex_);

    int64_t now = nowMs();
    cleanupIfExpiredHash(key, now);

    auto it = hmap_.find(key);
    if (it == hmap_.end())
        return std::nullopt;
    auto itf = it->second.fields.find(field);
    if (itf == hmap_[key].fields.end())
    {
        return std::nullopt;
    }

    return itf->second;
}

int KeyValueStore::hdel(const std::string&              key,
                        const std::vector<std::string>& fields)
{
    std::lock_guard<std::mutex> lock(mutex_);

    int64_t now = nowMs();
    cleanupIfExpiredHash(key, now);

    auto it = hmap_.find(key);
    if (it == hmap_.end())
    {
        return 0;
    }

    int removed = 0;

    for (auto& field : fields)
    {
        auto itf = it->second.fields.find(field);
        if (itf != it->second.fields.end())
        {
            it->second.fields.erase(itf);
            ++removed;
        }
    }

    if (it->second.fields.empty())
    {
        hmap_.erase(it);
    }

    return removed;
}

bool KeyValueStore::hexists(const std::string& key,
                            const std::string& field)
{
    std::lock_guard<std::mutex> lock(mutex_);

    int64_t now = nowMs();
    cleanupIfExpiredHash(key, now);

    auto it = hmap_.find(key);
    if (it == hmap_.end())
    {
        return false;
    }

    return it->second.fields.find(field) != it->second.fields.end();
}

std::vector<std::string> KeyValueStore::hgetallFlat(const std::string& key)
{
    std::lock_guard<std::mutex> lock(mutex_);

    int64_t now = nowMs();
    cleanupIfExpiredHash(key, now);

    std::vector<std::string> out;
    auto                     it = hmap_.find(key);
    if (it == hmap_.end())
    {
        return out;
    }

    out.reserve(it->second.fields.size() * 2);
    for (auto& kv : it->second.fields)
    {
        out.emplace_back(kv.first);
        out.emplace_back(kv.second);
    }

    return out;
}

int KeyValueStore::hlen(const std::string& key)
{
    std::lock_guard<std::mutex> lock(mutex_);

    int64_t now = nowMs();
    cleanupIfExpiredHash(key, now);
    auto it = hmap_.find(key);
    if (it == hmap_.end())
        return 0;

    return static_cast<int>(it->second.fields.size());
}

bool KeyValueStore::setHashExpireAtMs(const std::string& key,
                                      int64_t            expire_at_ms)
{
    std::lock_guard<std::mutex> lock(mutex_);

    int64_t now = nowMs();
    cleanupIfExpiredHash(key, now);

    auto it = hmap_.find(key);
    if (it == hmap_.end())
        return false;

    it->second.expire_at_ms = expire_at_ms;
    if (expire_at_ms >= 0)
    {
        expire_index_[key] = expire_at_ms;
    }
    else
    {
        expire_index_.erase(key);
    }

    return true;
}

HashRecordVector KeyValueStore::snapshotHash() const
{
    std::lock_guard<std::mutex> lock(mutex_);

    std::vector<std::pair<std::string, HashRecord>> out;
    out.reserve(hmap_.size());
    for (const auto& kv : hmap_)
        out.emplace_back(kv.first, kv.second);

    return out;
}

/**********************哈希****************************/

/**********************有序集合****************************/
int KeyValueStore::zadd(const std::string& key, double score,
                        const std::string& member)
{
    std::lock_guard<std::mutex> lock(mutex_);
    int64_t                     now = nowMs();
    cleanupIfExpiredZSet(key, now);

    // 获取有序集合的记录
    auto& rec = zmap_[key];

    // 检查成员是否已存在
    auto mit = rec.member_to_score.find(member);

    // 分情况处理：成员不存在（新增）
    if (mit == rec.member_to_score.end())
    {
        if (!rec.use_skiplist)
        {
            auto& vec = rec.items;

            // 找到插入位置：保持vector有序（按分数升序，分数相同则按成员字符串升序）
            auto it = std::lower_bound(vec.begin(), vec.end(),
                                       std::make_pair(score, member),
                                       [](const auto& a, const auto& b) {
                                           if (a.first != b.first)
                                               return a.first < b.first;
                                           return a.second < b.second;
                                       });

            vec.insert(it, std::make_pair(score, member));

            if (vec.size() > kZsetVectorThreshold)
            {
                rec.use_skiplist = true;
                rec.sl           = std::make_unique<Skiplist>();
                for (const auto& pr : vec)
                {
                    rec.sl->insert(pr.first, pr.second);
                }
                std::vector<std::pair<double, std::string>>().swap(
                    rec.items);
            }
        }
        else
        {
            rec.sl->insert(score, member);
        }

        rec.member_to_score.emplace(member, score);
        return 1;
    }

    // 分情况处理：成员已存在（更新分数）
    double old = mit->second;
    if (old == score)
        return 0;

    if (!rec.use_skiplist)
    {
        auto& vec = rec.items;

        // 先从vector中删除旧的<旧分数, 成员>对
        for (auto vit = vec.begin(); vit != vec.end(); ++vit)
        {
            if (vit->first == old && vit->second == member)
            {                      // 找到旧记录
                vec.erase(vit);    // 删除
                break;
            }
        }

        auto it = std::lower_bound(vec.begin(), vec.end(),
                                   std::make_pair(score, member),
                                   [](const auto& a, const auto& b) {
                                       if (a.first != b.first)
                                           return a.first < b.first;
                                       return a.second < b.second;
                                   });

        vec.insert(it, std::make_pair(score, member));

        if (vec.size() > kZsetVectorThreshold)
        {
            rec.use_skiplist = true;
            rec.sl           = std::make_unique<Skiplist>();
            for (const auto& pr : vec)
            {
                rec.sl->insert(pr.first, pr.second);
            }
            std::vector<std::pair<double, std::string>>().swap(rec.items);
        }
    }
    else
    {

        rec.sl->erase(old, member);
        rec.sl->insert(score, member);
    }

    mit->second = score;
    return 0;    // 返回0表示更新完成（非新增）
}

int KeyValueStore::zrem(const std::string&              key,
                        const std::vector<std::string>& members)
{
    std::lock_guard<std::mutex> lock(mutex_);

    int64_t now = nowMs();
    cleanupIfExpiredZSet(key, now);

    auto it = zmap_.find(key);
    if (it == zmap_.end())    // 如果找不到（不存在或已过期被清理）
        return 0;             // 直接返回0（没有成员被删除）

    int removed = 0;
    for (const auto& m : members)
    {
        // 1、在哈希表中查找成员m是否存在（快速判断）
        auto mit = it->second.member_to_score.find(m);
        if (mit == it->second.member_to_score.end())
        {
            continue;
        }

        // 2、获取成员m的分数（用于在存储结构中定位）
        double sc = mit->second;

        // 3、先从哈希表中删除该成员（因为哈希表只是记录映射，不涉及有序存储）
        it->second.member_to_score.erase(mit);

        // 4、根据当前存储结构（vector或跳表），删除对应的有序记录
        if (!it->second.use_skiplist)
        {
            auto& vec = it->second.items;
            for (auto vit = vec.begin(); vit != vec.end(); ++vit)
            {
                if (vit->first == sc && vit->second == m)
                {
                    vec.erase(vit);
                    ++removed;
                    break;
                }
            }
        }
        else
        {
            if (it->second.sl->erase(sc, m))
                removed++;
        }
    }

    // 如果当前用vector存储，且vector已空（没有任何成员了）
    if (!it->second.use_skiplist)
    {
        if (it->second.items.empty())
            zmap_.erase(it);
    }
    else
    {
        // 如果当前用跳表存储，且跳表大小为0（没有任何成员了）
        if (it->second.sl->size() == 0)
            zmap_.erase(it);    // 从zmap_中删除这个空集合+
    }

    return removed;
}

std::vector<std::string> KeyValueStore::zrange(const std::string& key,
                                               int64_t start, int64_t stop)
{
    std::lock_guard<std::mutex> lock(mutex_);

    int64_t now = nowMs();
    cleanupIfExpiredZSet(key, now);

    std::vector<std::string> out;

    auto it = zmap_.find(key);
    if (it == zmap_.end())
        return out;
    if (!it->second.use_skiplist)
    {
        const auto& vec = it->second.items;
        int64_t     n   = static_cast<int64_t>(vec.size());
        if (n == 0)
            return out;
        auto norm = [&](int64_t idx) {
            if (idx < 0)
                idx = n + idx;
            if (idx < 0)
                idx = 0;
            if (idx >= n)
                idx = n - 1;
            return idx;
        };
        int64_t s = norm(start), e = norm(stop);
        if (s > e)
            return out;
        for (int64_t i = s; i <= e; ++i)
            out.push_back(vec[static_cast<size_t>(i)].second);
    }
    else
    {
        it->second.sl->rangeByRank(start, stop, out);
    }
    return out;
}

std::optional<double> KeyValueStore::zscore(const std::string& key,
                                            const std::string& member)
{
    std::lock_guard<std::mutex> lock(mutex_);

    int64_t now = nowMs();
    cleanupIfExpiredZSet(key, now);
    auto it = zmap_.find(key);
    if (it == zmap_.end())
        return std::nullopt;
    auto mit = it->second.member_to_score.find(member);
    if (mit == it->second.member_to_score.end())
        return std::nullopt;
    return mit->second;
}

bool KeyValueStore::setZSetExpireAtMs(const std::string& key,
                                      int64_t            expire_at_ms)
{
    std::lock_guard<std::mutex> lock(mutex_);

    auto it = zmap_.find(key);
    if (it == zmap_.end())
        return false;
    it->second.expire_at_ms = expire_at_ms;
    if (expire_at_ms >= 0)
        expire_index_[key] = expire_at_ms;
    else
        expire_index_.erase(key);
    return true;
}

std::vector<KeyValueStore::ZSetFlat> KeyValueStore::snapshotZSet() const
{
    std::lock_guard<std::mutex> lock(mutex_);

    std::vector<ZSetFlat> out;
    out.reserve(zmap_.size());

    for (const auto& kv : zmap_)
    {
        ZSetFlat flat;
        flat.key          = kv.first;
        flat.expire_at_ms = kv.second.expire_at_ms;

        if (!kv.second.use_skiplist)
            flat.items = kv.second.items;
        else
            kv.second.sl->toVector(flat.items);

        out.emplace_back(std::move(flat));
    }
    return out;
}

std::vector<std::string> KeyValueStore::listKeys() const
{
    std::lock_guard<std::mutex> lock(mutex_);
    std::vector<std::string>    out;
    out.reserve(map_.size() + hmap_.size() + zmap_.size());
    for (const auto& kv : map_)
        out.push_back(kv.first);
    for (const auto& kv : hmap_)
        out.push_back(kv.first);
    for (const auto& kv : zmap_)
        out.push_back(kv.first);
    // 去重
    std::sort(out.begin(), out.end());
    out.erase(std::unique(out.begin(), out.end()), out.end());
    return out;
}

bool KeyValueStore::isExpired(const ZSetRecord& r, int64_t now_ms)
{
    return r.expire_at_ms >= 0 && now_ms >= r.expire_at_ms;
}

void KeyValueStore::cleanupIfExpiredZSet(const std::string& key, int64_t now_ms)
{
    auto it = zmap_.find(key);
    if (it == zmap_.end())
        return;
    if (isExpired(it->second, now_ms))
    {
        zmap_.erase(it);
        expire_index_.erase(key);
    }
}

/**********************有序集合****************************/

}    // namespace mini_redis